package com.xyulu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.sun.org.apache.regexp.internal.RE;
import com.xyulu.dao.BlogArticleDao;
import com.xyulu.entity.BlogArticleEntity;
import com.xyulu.entity.BlogArticleTagEntity;
import com.xyulu.entity.common.CommonField;
import com.xyulu.entity.common.PageBean;
import com.xyulu.entity.common.RedisConstant;
import com.xyulu.entity.vo.ArticleQuery;
import com.xyulu.service.BlogArticleService;
import com.xyulu.service.BlogArticleTagService;
import com.xyulu.service.BlogCategoryService;
import com.xyulu.utils.MarkdownUtil;
import com.xyulu.utils.RedisUtil;
import com.xyulu.utils.ShiroUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author lumin
 * @since 2021-02-25
 */
@Service
@Transactional
public class BlogArticleServiceImpl extends ServiceImpl<BlogArticleDao, BlogArticleEntity> implements BlogArticleService {

    @Resource
    private BlogCategoryService categoryService;

    @Resource
    private BlogArticleTagService articleTagService;

    @Override
    public List<BlogArticleEntity> findArticleViews(PageBean page) {
        //开启分页
        int total = baseMapper.findArticleViews().size();
        page.setRecordCount(total);
        page.setPageCount(total/page.getPageSize()+1);
        PageHelper.startPage(page.getCurrentPage(), page.getPageSize());
        List<BlogArticleEntity> articles = baseMapper.findArticleViews();

        return articles;
    }

    @Override
    public void updateView(Integer view, Integer id) {
        baseMapper.updateView(view,id);
    }

    @Override
    public void updateComment(Integer comment, Integer id) {
        baseMapper.updateComment(comment,id);
    }

    @Override
    public void toRecycleBin(List<String> ids) {
        baseMapper.toRecycleBin(ids);
    }

    @Override
    public void releaseArticle(BlogArticleEntity articleEntity) {
        handleArticleEntity(articleEntity);
        //将发布的封面保存到redis的cover_img_upload中 TODO

        //保存文章，返回主键id
        baseMapper.insert(articleEntity);
        //创建文章和标签的映射关系
        List<BlogArticleTagEntity> cons = new ArrayList<>();
        for (String tag : articleEntity.getTagIds().split(",")) {
            cons.add(new BlogArticleTagEntity(articleEntity.getId(), Long.parseLong(tag)));
        }
        articleTagService.saveBatch(cons);
    }

    @Override
    public void editArticle(BlogArticleEntity articleEntity) {
        handleArticleEntity(articleEntity);
        //去除旧映射关系
        articleTagService.removeArticleTagConns(articleEntity.getId());
        //创建文章和标签的映射关系
        List<BlogArticleTagEntity> cons = new ArrayList<>();
        for (String tag : articleEntity.getTagIds().split(",")) {
            cons.add(new BlogArticleTagEntity(articleEntity.getId(), Long.parseLong(tag)));
        }
        articleTagService.saveBatch(cons);
        this.updateById(articleEntity);
    }

    /**
     * 需要保存的文章实体类
     * @param articleEntity
     */
    private void handleArticleEntity(BlogArticleEntity articleEntity) {
        articleEntity.setAuthor(ShiroUtil.getLocalUserId());
        //生成对应的html页面
        articleEntity.setContentHtml(MarkdownUtil.markdownToHtmlExtensions(articleEntity.getContentMd()));
        String desc = articleEntity.getContentMd().trim();
        if (articleEntity.getContentMd().trim().length() > 250) {
            desc = articleEntity.getContentMd().trim().substring(0, 250) + "......";
        }
        articleEntity.setArticleDesc(desc);
    }

    @Override
    public List<BlogArticleEntity> showArticles(ArticleQuery query, PageBean pageBean) {
        QueryWrapper<BlogArticleEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(BlogArticleEntity::getStatus,CommonField.ARTICLE_RELEASE_STATUS)
                .eq(BlogArticleEntity::getIsView, CommonField.ARTICLE_IS_VIEW);
        //分类搜索条件
        if (query.getCategory() != null) {
            wrapper.lambda().eq(BlogArticleEntity::getArticleCategory,query.getCategory());
            pageBean.setCondition("?category="+query.getCategory());
        }
        //标签搜索条件
        if (StringUtils.isNotEmpty(query.getTag())) {
            wrapper.lambda().like(BlogArticleEntity::getTagIds,query.getTag());
            pageBean.setCondition("?tag="+query.getTag());
        }
        //标题搜索条件
        if (StringUtils.isNotEmpty(query.getTitle())) {
            wrapper.lambda().like(BlogArticleEntity::getArticleTitle,query.getTitle());
            pageBean.setCondition("?search="+query.getTitle());
        }
        int total = this.count(wrapper);
        //构造分页对象
        pageBean.setRecordCount(total);
        pageBean.setPageCount(total/pageBean.getPageSize()+1);
        PageHelper.startPage(pageBean.getCurrentPage(), pageBean.getPageSize());
        List<BlogArticleEntity> articles = this.list(wrapper);
        return articles;
    }

    @Override
    public List<BlogArticleEntity> topViews() {
        QueryWrapper<BlogArticleEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(BlogArticleEntity::getStatus,"0")
                .eq(BlogArticleEntity::getIsView,"1")
                .orderByDesc(BlogArticleEntity::getTotalView);
        PageHelper.startPage(0,5);
        List<BlogArticleEntity> topViews = this.list(wrapper);
        return topViews;
    }

    @Override
    public List<BlogArticleEntity> latestArticles() {
        QueryWrapper<BlogArticleEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(BlogArticleEntity::getStatus,"0")
                .eq(BlogArticleEntity::getIsView,"1")
                .orderByDesc(BlogArticleEntity::getCreateTime);
        PageHelper.startPage(0,5);
        return this.list(wrapper);
    }

}
